home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
jwpsrc.zip
/
DICT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-31
|
21KB
|
748 lines
/* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
#include "jwp.h"
#include "idm.h"
#define DICTINDENT 5
#define NRCACHE 20
typedef struct {
long int offset;
KANJI far *string;
} DICTCACHE;
static BOOL DictOK = FALSE;
static OFSTRUCT dictof, idxof;
static DICTCACHE cache[NRCACHE];
static KANJI far *ConvertOffset (int id, LONG lParam, KANJI *buf)
{
FILE *fp;
int fd, i, j, ch;
long int offset;
int length;
length = (lParam >> 24) & 0x00ff;
offset = lParam & 0x00ffffff;
/* In the cache? */
for (i = 0; i < NRCACHE; i++) {
if (cache[i].string == NULL) continue;
if (cache[i].offset == offset) break;
}
if (i < NRCACHE) return (cache[i].string);
/* Not in the cache */
buf[0] = 0;
fd = OpenFile(NULL, &dictof, OF_READ | OF_REOPEN);
fp = fdopen(fd, "rb");
if (fp == NULL) {
close(fd);
return ((KANJI far *) buf);
}
fseek(fp, offset, 0);
for (i = j = 0; j < length; i++) {
ch = getc(fp);
j++;
if (ch & 0x80) {
ch &= 0x007f;
buf[i] = (ch << 8) | (getc(fp) & 0x007f);
j++;
} else if (ch == '/') {
buf[i++] = ',';
buf[i] = ' ';
} else {
buf[i] = ch;
}
}
buf[i] = 0;
fclose(fp);
if (i <= 0) {
return ((KANJI far *) buf);
} else if (!ISKANJI(buf[0])) {
for (; i >= 0; i--) buf[i+DICTINDENT] = buf[i];
for (i = 0; i < DICTINDENT; i++) buf[i] = ' ';
} else {
for (i = 0; buf[i] != 0; i++) {
if (buf[i] == '[') buf[i] = 0x215a;
else if (buf[i] == ']') buf[i] = 0x215b;
else if (buf[i] == ' ') buf[i] = 0x2121;
}
}
/* Put in the cache */
for (i = 0; i < NRCACHE && cache[i].string != NULL; i++);
if (i >= NRCACHE) {
long int diff, maxdiff;
for (i = maxdiff = 0, j = -1; i < NRCACHE; i++) {
diff = cache[i].offset - offset;
if (diff < 0) diff = -diff;
if (diff > maxdiff) {
j = i;
maxdiff = diff;
}
}
if (j < 0) j = rand() % NRCACHE;
i = j;
}
if (cache[i].string != NULL) FreeBlock(cache[i].string);
cache[i].string = (KANJI far *) BlockAlloc((kanjilen(buf) + 5) * sizeof(KANJI));
cache[i].offset = offset;
kanjicpy(cache[i].string, buf);
return ((KANJI far *) buf);
}
static BOOL CheckDictionary (void)
{
int fd;
long int indexsize;
long int dictsize;
if (DictOK) return (TRUE);
for (;;) {
fd = OpenFile(global.jdict, &dictof, OF_READ);
if (fd >= 0) break;
if (!RetryMessage ("Cannot open dictionary '%s'!", global.jdict))
return (FALSE);
}
lseek(fd, 0L, 2);
dictsize = tell(fd);
close(fd);
for (;;) {
fd = OpenFile(global.jdictidx, &idxof, OF_READ);
if (fd >= 0) break;
if (!RetryMessage ("Cannot open dictionary index '%s'!", global.jdictidx))
return (FALSE);
}
lseek(fd, 0L, 0);
read(fd, &indexsize, sizeof(long int));
close(fd);
if (indexsize != dictsize + 15) {
ErrorMessage(global.hwnd, "This index file does not belong to this dictionary!");
return (FALSE);
}
DictOK = TRUE;
return (TRUE);
}
static int DictComp (BYTE *p1, BYTE *p2, int n)
{
int i;
BYTE c1, c2;
BOOL f1 = FALSE, f2 = FALSE;
for (i = 0; ; i++, p1++, p2++) {
if (n > 0 && i >= n) return (0);
c1 = *p1;
c2 = *p2;
if ('A' <= c1 && c1 <= 'Z') c1 += 32;
if ('A' <= c2 && c2 <= 'Z') c2 += 32;
if (c1 & 0x80) {
f1 = !f1;
if (f1 && c1 == 0xa5) c1 = 0xa4; /* Katakana? */
} else {
f1 = FALSE;
}
if (c2 & 0x80) {
f2 = !f2;
if (f2 && c2 == 0xa5) c2 = 0xa4; /* Katakana? */
} else {
f2 = FALSE;
}
if (c1 != c2) return (c1 - c2);
if (c1 == 0) return (0);
}
return (c1 - c2);
}
static int SearchDictionary (HWND DlgHwnd, HWND KeyHwnd, HWND ListHwnd)
{
int i, j, k, last, len;
int fd, nr_matches;
BOOL PassedKanji, Duplicate;
FILE *fp;
long int nr_index;
long int top, bottom, middle;
long int offset, cut, temp;
int diff, length;
MSG msg;
BYTE key[MAXLINELEN], target[MAXLINELEN];
KANJI ch;
UNIT far *up;
RECT rect;
/* Deletes everything from the list box */
if (SendMessage(ListHwnd, LB_GETCOUNT, 0, 0L) > 0)
SendMessage(ListHwnd, LB_RESETCONTENT, 0, 0L);
while (PeekMessage(&msg, DlgHwnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/* Opens the dictionary and index files */
fd = OpenFile(NULL, &dictof, OF_READ | OF_REOPEN);
if (fd < 0) return (0);
fp = fdopen(fd, "rb");
if (fp == NULL) {
close(fd);
return (0);
}
fd = OpenFile(NULL, &idxof, OF_READ | OF_REOPEN);
if (fd < 0) {
fclose(fp);
return (0);
}
lseek(fd, 0L, 2); /* Move to EOF */
nr_index = (tell(fd) / sizeof(long int)) - 1;
nr_matches = 0;
/* Create the key string */
up = (UNIT far *) SendMessage(KeyHwnd, EM_GETLINE, 0, 0L);
for (i = j = 0; ; j++) {
ch = up[j].kanji;
if (ch == 0) break;
if (ISKANJI(ch)) {
key[i++] = HIBYTE(ch) | 0x0080;
key[i++] = LOBYTE(ch) | 0x0080;
} else {
key[i++] = ch;
}
}
key[i] = '\0';
length = i;
/* Binary Search */
top = 0;
bottom = nr_index - 1;
for (;;) {
middle = (top + bottom) / 2;
/* Get the offset */
lseek(fd, (middle + 1) * sizeof(long int), 0);
read(fd, &offset, sizeof(long int));
/* Get the target string */
fseek(fp, offset - 1, 0);
fgets(target, MAXLINELEN, fp);
diff = DictComp(key, target, -1);
if (diff == 0) {
cut = middle;
break;
}
if (top >= bottom - 1) {
cut = bottom;
break;
}
if (diff > 0) top = middle;
else bottom = middle;
}
SendMessage(ListHwnd, WM_SETREDRAW, FALSE, 0L);
GetClientRect(ListHwnd, &rect);
rect.right -= 2 * GetSystemMetrics(SM_CXVSCROLL);
for (;; cut++) {
/* Now, did the user abort? */
if (PeekMessage(&msg, DlgHwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) {
if (msg.message == WM_CHAR && msg.wParam == '\x1b') {
if (YesNo(DlgHwnd, "Dictionary search interrupted!\n\nContinue?") != IDYES) break;
} else {
TranslateMessage(&msg);
}
//DispatchMessage(&msg);
}
lseek(fd, (cut + 1) * sizeof(long int), 0);
read(fd, &offset, sizeof(long int));
/* Get the text string */
offset--;
fseek(fp, offset, 0);
fgets(target, MAXLINELEN, fp);
/* Still matches? */
if (DictComp(key, target, length)) break;
nr_matches++;
if (nr_matches > 0) {
char tempbuf[50];
sprintf(tempbuf, "%d match%s", nr_matches, (nr_matches > 1) ? "es" : "");
SetDlgItemText(GetParent(KeyHwnd), 4202, tempbuf);
}
/* OK, now backseek to the beginning of the line, shall we? */
fseek(fp, offset, 0);
for (;;) {
if (offset < MAXLINELEN) {
fseek(fp, 0L, 0);
j = offset;
offset = 0L;
} else {
fseek(fp, -MAXLINELEN, 1); /* Get the previous block */
j = MAXLINELEN;
offset -= MAXLINELEN;
}
fread